/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateful;

import entity.*;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Dao Thai Duy
 */
@Stateful
@LocalBean
public class TransactionSessionBean {

    @PersistenceContext
    private EntityManager entityManager;
    StakeholderSessionBeanStateful stakeholderSessionBean;

    //change return type to Transaction 
    public TransactionsEntity createTransaction(Double amount, String description, String paypalTransactionId, String paypalCorrelationId,
            TouristAccountEntity tourist, ReservationEntity reservation, StakeholderEntity stakeholder,
            PaymentManagementEntity paymentManagement, String purpose) {
        System.out.println("Create transaction begin");
        Date date = new Date();
        TransactionsEntity transaction = new TransactionsEntity();
        transaction.setAmount(amount);
        transaction.setDescription(description);
        transaction.setPaypalTransactionId(paypalTransactionId);
        transaction.setPaypalCorrelationId(paypalCorrelationId);
        transaction.setTourist(tourist);
        transaction.setReservation(reservation);
        transaction.setStakeholder(stakeholder);
        transaction.setPaymentManagement(paymentManagement);
        transaction.setDatePaid(date);
        entityManager.persist(transaction);
        System.out.println("get purpose");
        if (purpose != null && purpose.equals("payCurrentBill")) {
            paymentManagement = entityManager.find(PaymentManagementEntity.class, paymentManagement.getId());
            paymentManagement.setOutstandingBilling(0);
            paymentManagement.setExpired(true);
        }

        if (purpose != null && purpose.equals("Refund")) {
            System.out.println("It's refund");
            tourist.getTransactions().add(transaction);
            entityManager.merge(tourist);
            if (reservation != null) {
                reservation.getTransactions().add(transaction);
                entityManager.merge(reservation);
            }
        }

        return transaction;
    }

    public List<TransactionsEntity> getAllTouristTransactions() {
        Query query = entityManager.createQuery("SELECT t FROM TransactionsEntity t");
        return query.getResultList();
    }

    public List<PaymentItemEntity> getAllStakeholderTransactions() {
        Query query = entityManager.createQuery("SELECT p FROM PaymentItemEntity p");
        return query.getResultList();
    }

    public List<TransactionsEntity> getTouristTransactionsByDate(Date startDate, Date endDate) {
        Query query = entityManager.createQuery("SELECT t FROM TransactionsEntity t WHERE t.datePaid >= :startDate AND t.datePaid <= :endDate");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);
        return query.getResultList();
    }

    public List<PaymentItemEntity> getStakeholderTransactionsByDate(Date startDate, Date endDate) {
        Query query = entityManager.createQuery("SELECT p FROM PaymentItemEntity p WHERE p.datePaid >= :startDate AND p.datePaid <= :endDate");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);
        return query.getResultList();
    }

    public void addIntoPaymentManagement(String paymentManagementID, PaymentItemEntity paymentItem) {
        PaymentManagementEntity paymentManagement = entityManager.find(PaymentManagementEntity.class, paymentManagementID);
        paymentManagement.setTotalPaymentCurrent(paymentManagement.getTotalPaymentCurrent() + paymentItem.getAmountToStakeholder());
        paymentManagement.getPaymentItem().add(paymentItem);
    }

    public void addTransaction(Double amount, Date datePaid, Time timePaid, ReservationEntity reservation, TouristAccountEntity tourist) {
        TransactionsEntity transaction = new TransactionsEntity();
        transaction.setAmount(amount);
        transaction.setTourist(tourist);
        transaction.setDatePaid(datePaid);
        transaction.setTimePaid(timePaid);
        transaction.setReservation(reservation);
        transaction.setTourist(tourist);
        entityManager.persist(transaction);
    }

    public List<PaymentItemEntity> getPaymentItemOfStakeholder(StakeholderEntity stakeholder, Date startDate, Date endDate) {
        List<PaymentItemEntity> paymentItems;
        paymentItems = stakeholder.getPaymentItem();

        return paymentItems;
    }

    public PaymentManagementEntity getPaymentManagementById(Long id) {
        return entityManager.find(PaymentManagementEntity.class, id);
    }

    public PaymentManagementEntity getCurrentBill(StakeholderEntity stakeholderEntity) {
        PaymentManagementEntity currentBill = null;
        stakeholderEntity = entityManager.find(StakeholderEntity.class, stakeholderEntity.getId());
        List<PaymentManagementEntity> paymentManagementList = stakeholderEntity.getPaymentManagement();

        for (int i = 0; i < paymentManagementList.size(); i++) {
            if (!paymentManagementList.get(i).isExpired()) {
                System.out.println("we have outstanding bill here");
                currentBill = paymentManagementList.get(i);
                break;
            }
        }
        return currentBill;
    }

    public void createChangeReservationTransaction(Double valueOf, String description, String paypalTransactionId, String paypalCorrelationId, TouristAccountEntity tourist, ReservationEntity reservation, String purpose) {
        System.out.println("begin create change reservation");
        TransactionsEntity transaction = createTransaction(valueOf, description, paypalTransactionId, paypalCorrelationId,
                tourist, reservation, null, null, purpose);
        System.out.println("after create transaction");
        tourist = entityManager.find(TouristAccountEntity.class, tourist.getId());
        tourist.getTransactions().add(transaction);
        reservation = entityManager.find(FnBReservationEntity.class, reservation.getId());
        reservation.getTransactions().add(transaction);
        System.out.println("NOthing happended");
    }

    public long createMakeReservationTransaction(Double valueOf, String description, String paypalTransactionId, String paypalCorrelationId, TouristAccountEntity tourist, String purpose) {
        entityManager.merge(tourist);
        TransactionsEntity transaction = createTransaction(valueOf, description, paypalTransactionId, paypalCorrelationId,
                tourist, null, null, null, purpose);
        tourist = entityManager.find(TouristAccountEntity.class, tourist.getId());
        tourist.getTransactions().add(transaction);
        return transaction.getId();
    }
    //End method by Khanh Vu

    public void createPaymentManagement(StakeholderEntity stakeholder) {
        Double totalAmount = 0.0;
        PaymentManagementEntity latestBill;
        PaymentManagementEntity paymentManagement = new PaymentManagementEntity();
        List<PaymentItemEntity> paymentItemList;
        Date date = new Date();
        int i;

        latestBill = getCurrentBill(stakeholder);
        latestBill.setExpired(true);
        entityManager.merge(latestBill);
        paymentItemList = getCurrentPaymentItemList(stakeholder);
        System.out.println("Current PaymentItemList" + paymentItemList.size());
        for (i = 0; i < paymentItemList.size(); i++) {
            totalAmount += paymentItemList.get(i).getAmountToTCube() - paymentItemList.get(i).getAmountToStakeholder();
        }
        System.out.println("den day roi");
        System.out.println("totalAmount " + totalAmount);
        paymentManagement.setTotalPaymentCurrent(totalAmount);
        paymentManagement.setPaymentReceived(0.0);
        paymentManagement.setPaymentLeft(totalAmount);
        paymentManagement.setStartDate(paymentItemList.get(0).getDateCreated());
        paymentManagement.setEndDate(date);
        paymentManagement.setDueDate(date);
        paymentManagement.setStakeholder(stakeholder);
        paymentManagement.setPaymentItem(paymentItemList);
        paymentManagement.setExpired(false);
        if (totalAmount >= 0) {
            paymentManagement.setOutstandingBilling(totalAmount);
        } else {
            paymentManagement.setOutstandingBilling(0.0);
        }
        entityManager.persist(paymentManagement);
        stakeholder.getPaymentManagement().add(paymentManagement);
        entityManager.persist(paymentManagement);
        for (i = 0; i < paymentItemList.size(); i++) {
            paymentItemList.get(i).setPaid(true);
            paymentItemList.get(i).setPaymentManagement(paymentManagement);
            entityManager.merge(paymentItemList.get(i));
        }
    }

    public List<PaymentItemEntity> getCurrentPaymentItemList(StakeholderEntity stakeholder) {
        List<PaymentItemEntity> paymentItemList = new ArrayList<PaymentItemEntity>();
        List<PaymentItemEntity> resultPaymentItemList = new ArrayList<PaymentItemEntity>();

        paymentItemList = stakeholder.getPaymentItem();
        for (PaymentItemEntity p : paymentItemList) {
            if (!p.isPaid()) {
                resultPaymentItemList.add(p);
            }
        }
        System.out.println("PaymentItem List " + resultPaymentItemList.size());
        return resultPaymentItemList;
    }

    public void createTransaction(Double amount, String description, String paypalTransactionId, String paypalCorrelationId,
            TouristAccountEntity tourist, ReservationEntity reservation, StakeholderEntity stakeholder,
            PaymentManagementEntity paymentManagement) {
        Date date = new Date();
        TransactionsEntity transaction = new TransactionsEntity();
        transaction.setAmount(amount);
        transaction.setDescription(description);
        transaction.setPaypalTransactionId(paypalTransactionId);
        transaction.setPaypalCorrelationId(paypalCorrelationId);
        transaction.setTourist(tourist);
        transaction.setReservation(reservation);
        transaction.setStakeholder(stakeholder);
        transaction.setPaymentManagement(paymentManagement);
        transaction.setDatePaid(date);
        entityManager.persist(transaction);
    }

    public List<TransactionsEntity> getAllTransactions() {
        Query query = entityManager.createQuery("SELECT t FROM TransactionsEntity t");
        return query.getResultList();
    }

    public List<TransactionsEntity> getAllTransactionsByDate(Date startDate, Date endDate) {
        Query query = entityManager.createQuery("SELECT t FROM TransactionsEntity t WHERE t.datePaid >= :startDate AND t.datePaid <= :endDate");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);
        return query.getResultList();
    }

    public List<TransactionsEntity> getAllTransactionsTourist(TouristAccountEntity tourist) {
        return tourist.getTransactions();
    }

    public List<TransactionsEntity> getTransactionsTouristByDate(TouristAccountEntity tourist, Date startDate, Date endDate) {
        List<TransactionsEntity> transactions;
        List<TransactionsEntity> transactionsByDate = new ArrayList<TransactionsEntity>();
        int i;
        transactions = tourist.getTransactions();
        System.out.print("getTransactionsByDate");
        for (i = 0; i < transactions.size(); i++) {
            if (transactions.get(i).getDatePaid().compareTo(startDate) >= 0 && transactions.get(i).getDatePaid().compareTo(endDate) <= 0) {
                transactionsByDate.add(transactions.get(i));
            }
        }
        System.out.println("transactionByDate " + transactionsByDate.size());
        return transactionsByDate;
    }

    public List<TransactionsEntity> getAllTransactionsStakeholder(StakeholderEntity stakeholder) {
        return stakeholder.getTransaction();
    }

    public List<TransactionsEntity> getTransactionsStakeholderByDate(StakeholderEntity stakeholder, Date startDate, Date endDate) {
        List<TransactionsEntity> transactions;
        List<TransactionsEntity> transactionsByDate = new ArrayList<TransactionsEntity>();
        int i;
        transactions = stakeholder.getTransaction();
        System.out.print("getTransactionsByDate");
        for (i = 0; i < transactions.size(); i++) {
            if (transactions.get(i).getDatePaid().compareTo(startDate) >= 0 && transactions.get(i).getDatePaid().compareTo(endDate) <= 0) {
                transactionsByDate.add(transactions.get(i));
            }
        }
        System.out.println("transactionByDate " + transactionsByDate.size());
        return transactionsByDate;
    }

    public void updatePaymentManagement(PaymentManagementEntity paymentManagement) {
        Date date = new Date();
        paymentManagement.setExpired(true);
        paymentManagement.setOutstandingBilling(0.0);
        paymentManagement.setPaymentReceived(paymentManagement.getTotalPaymentCurrent());
        paymentManagement.setPaymentLeft(0.0);
        paymentManagement.setDatePaid(date);
    }
}
